package com.soup.bytebuddy.intercept;

import net.bytebuddy.implementation.bind.annotation.AllArguments;
import net.bytebuddy.implementation.bind.annotation.Argument;
import net.bytebuddy.implementation.bind.annotation.Origin;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.implementation.bind.annotation.SuperCall;

import java.lang.reflect.Method;
import java.util.concurrent.Callable;

/**
 * 〈方法调用信息监控〉<br>
 *
 * @author zhaoyi
 */
public class MonitorMethodInfo {
    /**
     *
     * @param method 获取方法信息
     *               @Origin 用于拦截原有方法，这样就可以获取到方法中的相关信息
     * @param args 用于获取全部参数
     * @param arg0 获取指定的参数
     * @param callable
     *              @SuperCall：用于调用父类版本的方法
     * @return
     * @throws Exception
     */
    @RuntimeType
    public static Object intercept(@Origin Method method, @AllArguments Object[] args, @Argument(0) Object arg0, @SuperCall Callable<?> callable) throws Exception {
        long start = System.currentTimeMillis();
        Object resObj = null;
        try {
            resObj = callable.call(); // 这个方法是调用原方法的内容，返回结果
            return resObj;
        } finally {
            System.out.println("方法名称：" + method.getName());
            System.out.println("入参个数：" + method.getParameterCount());
            System.out.println("入参类型：" + method.getParameterTypes()[0].getTypeName() + "、" + method.getParameterTypes()[1].getTypeName());
            System.out.println("入参内容：" + arg0 + "、" + args[1]);
            System.out.println("出参类型：" + method.getReturnType().getName());
            System.out.println("出参结果：" + resObj);
            System.out.println("方法耗时：" + (System.currentTimeMillis() - start) + "ms");
        }
    }
}
